約 3,882,643 件
https://w.atwiki.jp/dayzresistance/pages/12.html
コメントプラグイン @wikiのwikiモードでは #comment() と入力することでコメントフォームを簡単に作成することができます。 詳しくはこちらをご覧ください。 =>http //atwiki.jp/guide/17_60_ja.html たとえば、#comment() と入力すると以下のように表示されます。 名前 コメント
https://w.atwiki.jp/dayzresistance/pages/8.html
RSSを取り込んで一覧表示(showrss) #showrss(ここにRSSのURL) もしくは #rss(ここにRSSのURLを入力) と入力することで指定したRSSを取り込んで一覧表示します。 詳しくはこちらをご覧ください。 =>http //www1.atwiki.jp/guide/pages/266.html#id_b6d0b10d たとえば、#showrss(http //iphone.appinfo.jp/rss/pricedown/,target=blank,countrss,lasttime) と入力すると以下のように表示されます。 showrss プラグインエラー RSSが見つからないか、接続エラーです。
https://w.atwiki.jp/thiroyoshi/pages/29.html
MPIの使い方や、動作の仕方といったことのメモ MPIとは? MPIは「Message Passing Interface」ってもので、要するにメッセージでの送受信を行いノード間の協調を図るもの。 これ自体がプログラミング言語なのではなく、ライブラリである。 使用する際には、「mpi.h」または「mpi++.h」をインクルードする必要がある。 メッセージの送受信には用意されている関数を用いる。これにも色々な方法があるよう。 MPIの動作 基本的にMPIを使用する用にコンパイルしたものは、指定したノードの数で実行される。(ノードの数の指定はシェルスクリプトで) 各ノードで実行されるプログラムは実際には同じものが動いている。つまり、すべてmain関数から処理を行っている。 では、何が利点か?それは、各ノードにはプロセス毎にノードの番号(rank)が割り当てられており、これによってif文などを用いて処理の分担を行う。 つまり、MPIは「並列処理」というよりも「分散処理」という側面が強いとも言える。 MPIの使い方 とりあえずサンプルを載せる。 #include stdio.h #include string.h #include iostream #include "mpi++.h" using namespace std; int main(int argc, char* argv[]){ int my_rank; //ノードの番号 int p; //すべてのノードの合計数 int source; //メッセージの送信元番号 int dest; //メッセージの送信先番号 int tag = 0; //メッセージタグ char message[100]; //メッセージ MPI_Status status; MPI_Init( argc, argv); //MPI関数を呼び出すための初期化 MPI_Comm_rank(MPI_COMM_WORLD, my_rank); //今プログラムが走っているノードの番号(rank)を取得 MPI_Comm_size(MPI_COMM_WORLD, p); //ノードの合計数を取得 //printf("Hello! %d\n", my_rank); //cout "Hello! " my_rank endl; //rankが0でないノードでのみ実行する if(my_rank != 0){ //メッセージに以下の文を格納する sprintf(message, "Greetings from process %d", my_rank); //printf("My rank is %d\n", my_rank); //cout "My rank is " my_rank endl; dest = 0; //0ノードに送信先を設定 //0ノードにmessageを送信 MPI_Send(message, strlen(message)+1, MPI_CHAR, dest, tag, MPI_COMM_WORLD); } //0ノードで実行される else{ //全ノード分ループをまわす for(source = 1; source p; source++){ //source番目のノードからmessageを受け取り、 MPI_Recv(message, 100, MPI_CHAR, source, tag, MPI_COMM_WORLD, status); //表示 printf("%s\n", message); //cout message endl; } } //最後の処理 MPI_Finalize(); } 出力結果 %NQSII(INFO) ------- Output from job 0000 ------- Warning no access to tty (Bad file descriptor). Thus no job control in this shell. [0] Greetings from process 1 [0] Greetings from process 2 [0] Greetings from process 3 [0] Greetings from process 4 [0] Greetings from process 5 [0] Greetings from process 6 [0] Greetings from process 7 [0] Greetings from process 8 [0] Greetings from process 9 %NQSII(INFO) ------- Output from job 0001 ------- %NQSII(INFO) ------- Output from job 0002 ------- %NQSII(INFO) ------- Output from job 0003 ------- %NQSII(INFO) ------- Output from job 0004 ------- 出力の左端[0]は、0ノードでの出力を表している 各ノードでmain関数がそのまま流れており、if文でmy_rankを判定材料として処理を分担している。 各ノードは0ノードにメッセージを送り、0ノードはそれらを逐一読み取り、表示している。 どのメッセージをどこで受信するかを示すもの →つまり、このタグが合うところでのみメッセージの受信ができる 上記のサンプルで、コメントアウトしているprintfとcoutがある。 →printfはしっかり出力をするが、coutは他のスレッドの割り込みを禁止することができていないようで、表示が割り込まれることがあるので使用しないことをオススメする printfをコメントアウトしなかった場合の出力は以下 %NQSII(INFO) ------- Output from job 0000 ------- Warning no access to tty (Bad file descriptor). Thus no job control in this shell. [0] Hello! 0 [1] Hello! 1 [1] My rank is 1 [0] Greetings from process 1 [0] Greetings from process 2 [0] Greetings from process 3 [0] Greetings from process 4 [0] Greetings from process 5 [0] Greetings from process 6 [0] Greetings from process 7 [0] Greetings from process 8 [0] Greetings from process 9 %NQSII(INFO) ------- Output from job 0001 ------- [2] Hello! 2 [3] Hello! 3 [3] My rank is 3 [2] My rank is 2 %NQSII(INFO) ------- Output from job 0002 ------- [4] Hello! 4 [4] My rank is 4 [5] Hello! 5 [5] My rank is 5 %NQSII(INFO) ------- Output from job 0003 ------- [6] Hello! 6 [6] My rank is 6 [7] Hello! 7 [7] My rank is 7 %NQSII(INFO) ------- Output from job 0004 ------- [8] Hello! 8 [8] My rank is 8 [9] Hello! 9 [9] My rank is 9 各ノードでの出力がどれになっているか注意 また、スパコンでのMPIのプログラムの出力は、outputのファイルはできない。 出力結果は、実行後に作成される「run.sh.o(ジョブID)」というファイルに書き込まれている。 また、同時に出力されている「run.sh.e(ジョブID)」はエラー関係が出力されている。 さらにシェルスクリプトを紹介 #PBS -l cputim_job=00 05 00 //cpu動作時間 #PBS -l memsz_job=2gb //メモリサイズ #PBS -l cpunum_job=2 //使用コア数 #PBS -T vltmpi #PBS -b 5 //ノード数 #PBS -q PCL-B //使用マシン cd MPI_sample //ディレクトリ移動 mpirun_rsh -np 10 ${NQSII_MPIOPTS} ./a.out //数字の10は(ノード数)×(CPUコア数) 内積 これには、MPI_Reduce()という関数を使う。とりあえずサンプル。 #include stdio.h #include string.h #include"mpi++.h" using namespace std; //内積を実際に計算する関数(局所的な計算) int Serial_dot(int x[], int y[], int n){ int i; int sum = 0; for(i = 0; i n; i++) sum = sum + x[i]*y[i]; return sum; } //各ノードの内積をまとめる関数 //各ノードでSerial_dot()でそれぞれの内積を求めて、MPI_Reduce()でまとめる //0ノード以外の返り値は0 int Parallel_dot(int local_x[], int local_y[], int n_bar){ int local_dot; int dot = 0.0; int Serial_dot(int x[], int y[], int m); local_dot = Serial_dot(local_x, local_y, n_bar); printf("local_dot = %d\n", local_dot); MPI_Reduce( local_dot, dot, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); return dot; } int main(int argc, char* argv[]){ int n = 20; //全配列数 int my_rank; //ノード番号 int p; //全ノード数 //MPIの初期化 MPI_Init( argc, argv); //ノード番号取得 MPI_Comm_rank(MPI_COMM_WORLD, my_rank); //全ノード数取得 MPI_Comm_size(MPI_COMM_WORLD, p); int n_bar = n/p; //各ノードでの配列数 int x[n_bar]; int y[n_bar]; int dot; //求める内積 //printf("n_bar = %d\n", n_bar); //初期値設定 for(int i = 0; i n_bar; i++){ x[i] = my_rank; y[i] = my_rank; } //各ノードでの内積計算 dot = Parallel_dot(x,y,n_bar); //if(my_rank == 0) printf("dot = %d\n", dot); MPI_Finalize(); } 出力結果 %NQSII(INFO) ------- Output from job 0000 ------- Warning no access to tty (Bad file descriptor). Thus no job control in this shell. [0] local_dot = 0 [1] local_dot = 2 [1] dot = 0 [0] dot = 570 %NQSII(INFO) ------- Output from job 0001 ------- [2] local_dot = 8 [3] local_dot = 18 [3] dot = 0 [2] dot = 0 %NQSII(INFO) ------- Output from job 0002 ------- [4] local_dot = 32 [5] local_dot = 50 [5] dot = 0 [4] dot = 0 %NQSII(INFO) ------- Output from job 0003 ------- [6] local_dot = 72 [7] local_dot = 98 [7] dot = 0 [6] dot = 0 %NQSII(INFO) ------- Output from job 0004 ------- [8] local_dot = 128 [9] local_dot = 162 [9] dot = 0 [8] dot = 0 MPI_Reduce() 計算を行い、指定した根ノードにのみ計算結果を返す。 そのため、他の各ノードでは返り値は0である。 各引数は次のようになっている。 int MPI_Reduce( void operand, //計算したい値のポインタ void result, //計算した結果を保存するポインタ int count, //データをいくつ送るか(数字1つなら1) MPI_Datatype datatype, //送信するデータの型(上ではMPI_INT) MPI_Op operator, //なんの計算をするか(上では総和をとるのでMPI_SUM) int root, //根ノードの番号(0でよい) MPI_Comm comm //特になにもなければMPI_COMM_WORLDでよい ){} MPI_Opについては定義済み操作が多く存在する。それらに関しては、windowsサーバに置いてあるMPIの教科書(p81)を参照のこと 計算結果が格納されるのは、rootに指定したノードでのresultにのみ。 MPI_Allreduce() MPI_Reduce()では根以外のノードでの返り値が0であったが、これでは全てのノードに計算結果を返すことができる。 引数はほぼMPI_Reduce()と同じ。 int MPI_ALLreduce( void operand, //計算したい値のポインタ void result, //計算した結果を保存するポインタ int count, //データをいくつ送るか(数字1つなら1) MPI_Datatype datatype, //送信するデータの型(上ではMPI_INT) MPI_Op operator, //なんの計算をするか(上では総和をとるのでMPI_SUM) MPI_Comm comm //特になにもなければMPI_COMM_WORLDでよい ){} 上記のサンプルプログラムで、MPI_Reduce()をMPI_AllReduce()にしたときの出力結果を示す %NQSII(INFO) ------- Output from job 0000 ------- Warning no access to tty (Bad file descriptor). Thus no job control in this shell. [0] local_dot = 0 [1] local_dot = 2 [0] dot = 570 [1] dot = 570 %NQSII(INFO) ------- Output from job 0001 ------- [2] local_dot = 8 [3] local_dot = 18 [2] dot = 570 [3] dot = 570 %NQSII(INFO) ------- Output from job 0002 ------- [4] local_dot = 32 [5] local_dot = 50 [5] dot = 570 [4] dot = 570 %NQSII(INFO) ------- Output from job 0003 ------- [6] local_dot = 72 [7] local_dot = 98 [7] dot = 570 [6] dot = 570 %NQSII(INFO) ------- Output from job 0004 ------- [8] local_dot = 128 [9] local_dot = 162 [9] dot = 570 [8] dot = 570 行列とベクトルの積 マトリクスとベクトルの積を並列に行うプログラム。 #include stdio.h #include string.h #include vector #include"mpi++.h" using namespace std; vector double MV(vector vector double iterator local_A, int m, int n, vector double iterator local_x, int local_m, int local_n){ vector double local_y; //計算用の一時変数 local_y.resize(local_n); vector double global_x; //ベクトル全体 global_x.resize(n); vector double global_y; //計算結果のベクトル global_y.resize(n); //各プロセスからベクトルxを集める MPI_Allgather(local_x, local_n, MPI_DOUBLE, global_x.begin(), local_n, MPI_DOUBLE, MPI_COMM_WORLD); //掛け算 for(int i = 0; i local_m; i++){ local_y[i] = 0.0; for(int j = 0; j n; j++) local_y[i] = local_y[i] + local_A[i][j]*global_x[j]; } //計算結果を集める MPI_Allgather(local_y.begin(), local_n, MPI_DOUBLE, global_y.begin(), local_n, MPI_DOUBLE, MPI_COMM_WORLD); return global_y; } int main(int argc, char* argv[]){ int n = 20; int m = 20; int my_rank; int p; MPI_Init( argc, argv); MPI_Comm_rank(MPI_COMM_WORLD, my_rank); MPI_Comm_size(MPI_COMM_WORLD, p); int local_n = n/p; int local_m = m/p; vector double x; vector vector double A; //掛け算する行列(各プロセスで一部ずつをもつ) A.resize(local_m); x.resize(local_n); //掛け算するベクトル(各プロセスで一部ずつをもつ) for(int i = 0; i local_m; i++) A[i].resize(n); for(int a = 0; a local_m; a++){ x[a] = my_rank; for(int b = 0; b n; b++) A[a][b] = 1.0; } //行列×ベクトル vector double y; y = MV(A.begin(),m,n,x.begin(),local_m,local_n); for(int i = 0; i n; i++) printf("y[%d] = %f\n",i,y[i]); MPI_Finalize(); } すぐに使えるであろう関数の形にまで落としこんだ。 行列×ベクトルを行っている部分をこれで置き換えれば、それで事足りるはず。 詳細な仕様はここには書きづらいので、直接聞いてもらえるといいかも。もちろんプログラムから察してくれれば一番だが。 が、簡単に書いておく ・行列A n×n行列。行方向で区切ったものを各プロセスでもつ。つまりlocal_Aはlocal_m×n行列になっている。 ・ベクトルx n行ベクトル。行方向で区切った部分を各プロセスでもつ。つまり各プロセスではlocal_m行のベクトル。 ・プロセス数と行数・列数 当然のことながら、行数・列数はプロセス数で割り切れなければならない。 最後に取得するベクトルyはn行の完全なベクトルになっている。上記のプログラムの出力結果は以下。 プロセス数10・行数列数20で計算 %NQSII(INFO) ------- Output from job 0000 ------- Warning no access to tty (Bad file descriptor). Thus no job control in this shell. [0] y[0] = 90.000000 [0] y[1] = 90.000000 [0] y[2] = 90.000000 [0] y[3] = 90.000000 [0] y[4] = 90.000000 [0] y[5] = 90.000000 [0] y[6] = 90.000000 [0] y[7] = 90.000000 [0] y[8] = 90.000000 [0] y[9] = 90.000000 [0] y[10] = 90.000000 [0] y[11] = 90.000000 [0] y[12] = 90.000000 [0] y[13] = 90.000000 [0] y[14] = 90.000000 [0] y[15] = 90.000000 [0] y[16] = 90.000000 [0] y[17] = 90.000000 [0] y[18] = 90.000000 [0] y[19] = 90.000000 [1] y[0] = 90.000000 [1] y[1] = 90.000000 [1] y[2] = 90.000000 [1] y[3] = 90.000000 [1] y[4] = 90.000000 [1] y[5] = 90.000000 [1] y[6] = 90.000000 [1] y[7] = 90.000000 [1] y[8] = 90.000000 [1] y[9] = 90.000000 [1] y[10] = 90.000000 [1] y[11] = 90.000000 [1] y[12] = 90.000000 [1] y[13] = 90.000000 [1] y[14] = 90.000000 [1] y[15] = 90.000000 [1] y[16] = 90.000000 [1] y[17] = 90.000000 [1] y[18] = 90.000000 [1] y[19] = 90.000000 … … ‥(以下同様) 行列と行列の積 一応できた。早いかはしらんw #include stdio.h #include string.h #include vector #include"mpi++.h" using namespace std; vector vector double MV(vector vector double iterator local_A, int m, int n, vector vector double iterator local_x, int local_m, int local_n){ vector double local_y; local_y.resize(local_n); vector double global_x; global_x.resize(n); vector vector double global_y; global_y.resize(n); for(int i = 0; i n; i++) global_y.resize(n); vector double global_tmp; global_tmp.resize(n); for(int k = 0; k n; k++){ MPI_Allgather(local_x[k].begin(), local_n, MPI_DOUBLE, global_x.begin(), local_n, MPI_DOUBLE, MPI_COMM_WORLD); for(int i = 0; i local_m; i++){ local_y[i] = 0.0; for(int j = 0; j n; j++) local_y[i] = local_y[i] + local_A[i][j]*global_x[j]; } MPI_Allgather(local_y.begin(), local_n, MPI_DOUBLE, global_tmp.begin(), local_n, MPI_DOUBLE, MPI_COMM_WORLD); global_y[k] = global_tmp; } return global_y; } int main(int argc, char* argv[]){ int n = 20; int m = 20; int my_rank; int p; MPI_Init( argc, argv); MPI_Comm_rank(MPI_COMM_WORLD, my_rank); MPI_Comm_size(MPI_COMM_WORLD, p); int local_n = n/p; int local_m = m/p; vector vector double A; vector vector double x; A.resize(local_m); for(int i = 0; i local_m; i++) A[i].resize(n); x.resize(n); for(int i = 0; i n; i++) x[i].resize(local_m); for(int a = 0; a local_m; a++){ for(int b = 0; b n; b++){ A[a][b] = 1.0; x[b][a] = my_rank; } } vector vector double y; y = MV(A.begin(),m,n,x.begin(),local_m,local_n); for(int i = 0; i n; i++){ for(int j = 0; j m; j++) printf("y[%d][%d] = %f\n",j,i,y[j][i]); } MPI_Finalize(); } 出力結果 %NQSII(INFO) ------- Output from job 0000 ------- Warning no access to tty (Bad file descriptor). Thus no job control in this shell. [0] y[0][0] = 90.000000 [1] y[0][0] = 90.000000 [1] y[1][0] = 90.000000 [1] y[2][0] = 90.000000 [1] y[3][0] = 90.000000 [1] y[4][0] = 90.000000 [1] y[5][0] = 90.000000 [1] y[6][0] = 90.000000 [1] y[7][0] = 90.000000 [1] y[8][0] = 90.000000 [1] y[9][0] = 90.000000 [1] y[10][0] = 90.000000 [1] y[11][0] = 90.000000 [1] y[12][0] = 90.000000 [1] y[13][0] = 90.000000 [1] y[14][0] = 90.000000 [1] y[15][0] = 90.000000 [1] y[16][0] = 90.000000 [1] y[17][0] = 90.000000 [1] y[18][0] = 90.000000 [1] y[19][0] = 90.000000 [1] y[0][1] = 90.000000 [1] y[1][1] = 90.000000 [1] y[2][1] = 90.000000 [1] y[3][1] = 90.000000 [1] y[4][1] = 90.000000 [1] y[5][1] = 90.000000 [1] y[6][1] = 90.000000 [1] y[7][1] = 90.000000 [1] y[8][1] = 90.000000 [1] y[9][1] = 90.000000 [1] y[10][1] = 90.000000 [1] y[11][1] = 90.000000 [1] y[12][1] = 90.000000 … … ‥(以下同様) #bf 名前 コメント
https://w.atwiki.jp/kumikomi-yitjc/pages/150.html
電圧などのアナログ値をデジタル値(数値)に変換する装置(ハードウエア)をA/D変換器(Analog to Digital Converter)という。 例えば、図の様なアナログの信号(電圧値)があった時に①の点では、2Vであったとすると、AD変換器(以下、ADC)を使えば、この電圧値を数値に変換する事が出来る。 ADCでアナログ電圧を数値に変換する事を、サンプリングと言う。サンプリングの周期は、アナログ電圧の周波数に対して、十分短い事が要求される。具体 的には、アナログ電圧の最大の周波数成分に対して2倍以上の速度でサンプルすれば良い事が知られている。(サンプリング定理) ただし、実用上は3倍以上、出来れば10倍程度の速度でサンプルすることが望ましい。 変換結果とアナログ電圧の関係 アナログ入力電圧は、ADCによって数値に変換される。この時、数値と実際の電圧との関係は、以下のようになる。 ADCの分解能は10bit(0~1023の数値を表現できる)なので、基準電圧を2.56Vとすると、この間を1024等分する事になる。つまり、 式:変換後の数値と入力電圧・基準電圧の関係 変換後の数値(ADCH、ADCL) = (入力電圧[V](ADC0~ADC12ピン) × 1023) / 2.56(基準電圧:VREF) ということになる。【注意】 ここで入力電圧の上限を5Vとしているが、正確には電源電圧が上限となる。従って、電池(3V)などでマイコンを動作させた場合は、3Vが上限になる事に注意。 (USB給電を行った場合は、5V) 上限を超える電圧を加えると、マイコンが破壊する。 AVRマイコン(ATMega32U4)に実装されているADCの主な仕様は、以下の通り 分解能10-bit 変換時間 13μs - 260μs アナログ入力12チャンネル(同時使用は1チャンネル) 入力可能電圧は 0 - VCC(USB使用の場合は+5V) 1.1Vの基準電圧源を内蔵 (2.56V ?) 連続変換、単発変換の切り替え 割り込みに対応 などである。 プログラミングの手順 設定内容は以下の通り、 AD変換器(以降、ADC)のON/OFF切り替え(ADCSRAレジスタ:ADENビット(第7ビット)) ADENビットを1にすることで、ADCを起動する。 ADCSRA |= _BV(ADEN); // AD変換器を起動 AD変換の起動設定(ADCSRA:ADATEビット(第5ビット)、ADCSRB:ADSTxビット(第0から第3ビット)) AD変換をスタート(トリガともいう)させるイベントを選択する。例えばタイマなどの比較一致などが選択できる。 ADATEビットを1にセットすると、ADCSRBレジスタのADTS3からADTS0ビットの設定が有効になる。それぞれ、以下のように機能が割り当てられている。 表:トリガモード一覧 ADCSRBレジスタ:bitの位置 (ビットの名前) 3 (ADTS3) 2 (ADTS2) 1 (ADTS1) 0 (ADTS0) 連続変換 0 0 0 0 アナログ比較器 0 0 0 1 外部割込み(IRQ0) 0 0 1 0 タイマ0 比較・一致 0 0 1 1 タイマ0 オーフロー(TCNT0) 0 1 0 0 タイマ1 比較・一致 (OCR1B) 0 1 0 1 タイマ1 オーバフロー(TCNT1) 0 1 1 0 タイマ1 キャプチャイベント 0 1 1 1 タイマ4 オーバフロー 1 0 0 0 タイマ4 比較・一致 (OCR4A) 1 0 0 1 タイマ4 比較・一致 (OCR4B) 1 0 1 0 タイマ4 比較・一致 (OCR4D) 1 0 1 1 連続変換(AD変換を1回だけでなく、連続してどんどん行わせる)の設定にしたいなら、以下の様にする。 ADCSRA |= _BV(ADATE); // ADATEビットを1に設定 ADCSRB = 0b11110000; // ADTS3~0ビットを0に設定 ADATEビットを0にして、ADSCビット(ADCSRA)を1にすると、AD変換は1回だけ行われる。 ADCSRA = ~_BV(ADATE); // ADCSRAレジスタは初期値が0なので、通常はこの設定は不要 割り込み設定(ADCSRA:ADIFビット(第4ビット)、ADIEビット(第3ビット)) AD変換終了時の割り込みを使うかどうかを選択する。ADIFビットは、割り込みが有効であるか否かにかかわらず、変換が終了した場合に1がセットされる。この状態でADIEビットに1が設定されていれば、割り込みハンドラが呼び出される。ADIFビットは、必要に応じてプログラムでクリアする必要がある。(1を書き込むと、クリア(=0)される) ADCSRA |= _BV(ADIE); // AD割り込みを許可 ADCSRA = ~_BV(ADIE); // AD割り込みを禁止 // 割り込みを使わないで、変換終了をチェックする if (ADCSRA _BV(ADIF)) { ADCSRA |= _BV(ADIF); // ADIFフラグをクリアする // AD変換終了 } else { // AD変換実行中 } 変換時間設定(ADCSRA:ADPS2~0ビット(第0~第2ビット)) AD変換器の変換時間を設定する。AD変換のクロックは50~200KHzの間で設定できる。(1変換につき13クロックが必要となる) ※ADCSRレジスタのビット配置を参照 システムクロックが16MHzで、変換速度を104uS(104マイクロ秒)としたいなら、以下の様にする。 ADCSRA |= _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0); // ADPS2~0ビットが111 これで、何故、104uSなのかというと、 ○16MHz = 16000000 Hzで、これを1/128するので、125000Hz。 ○1クロック当たりの時間は1/125000なので、0.000008秒(=8マイクロ秒) ○1回の変換に13クロック必要なので、0.000008 × 13 = 0.000104秒 (=104マイクロ秒) つまり、1/0.000104=9615.38... で、1秒間で9515.4回(9.5kSPS)、アナログデータを数値に変換する事が出来る。 「こんなんじゃ、全然速度が足らん」、というあなた! 変換精度を犠牲に出来るのなら、変換速度を上げることもできます。(77kSPS/8bit位が上限?) 変換結果の出力方法(ADMUXレジスタ:ADLARビット(第5ビット)) 変換結果はADCレジスタ(16ビット)に記録されるが、AD変換器の分解能は10ビットなので、長さが合わない。このため、変換結果を上位側に詰めるか、下位側にするかを選択する。具体的には以下の通り。 表:AD変換結果のレイアウト(ADCレジスタ上のデータの場所)ADLAR=1 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ADC9 ADC8 ADC7 ADC6 ADC5 ADC4 ADC3 ADC2 ADC1 ADC0 - - - - - - ADLAR=0 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 - - - - - - ADC9 ADC8 ADC7 ADC6 ADC5 ADC4 ADC3 ADC2 ADC1 ADC0 実際のアクセスでは、ADCレジスタは8ビットずつ分割して2回に分けて(下位、上位の順)アクセスする。 上位側のレジスタはADCH、下位側のレジスタはADCLであり、ADLARの設定で、以上の様にデータが設定されることに注意する事。 基準電圧の設定(ADMUXレジスタ:REFS1,0ビット(第7,6ビット)) AD変換の変換値の基準となる電圧を指定する。変換値への影響については、上の計算式(式:変換後の数値と入力電圧・基準電圧の関係)を参照のこと 表:基準電圧減の選択 ADMUXレジスタ:bitの位置 (ビットの名前) 7 (REFS1) 6 (REFS0) AREFピン(ボード上はVREFピン)を基準電圧とする。 0 0 AVCC(Davinci32Uは5V)を基準電圧とする。 0 1 予約 1 0 内部2.56V基準電圧 1 1 入力チャンネルの選択(ADMUXレジスタ:MUX4~0ビット(第4~第0ビット)、 ADCSRBレジスタ:MUX5ビット(第5ビット)) ATMega32U4には12本のアナログ入力がある。これをどのように切り替えて使うかを選択する。 表:アナログ入力チャンネルの選択 ビット MUX5~MUX0 シングルエンド入力ピン 差動入力 (プラス側)ピン 差動入力 (マイナス側)ピン 倍率 00 0000 ADC0 N/A 00 0001 ADC1 00 0010 N/A 00 0011 00 0100 ADC4 00 0101 ADC5 00 0110 ADC6 00 0111 ADC7 00 1000 N/A N/A N/A N/A 00 1001 ADC1 ADC0 10x 00 1010 N/A N/A N/A 00 1011 ADC1 ADC0 200x 00 1100 N/A 00 1101 00 1110 00 1111 01 0000 ADC0 ADC1 1x 01 0001 N/A 01 0010 01 0011 01 0100 ADC4 ADC1 1x 01 0101 ADC5 ADC1 1x 01 0110 ADC6 ADC1 1x 01 0111 ADC7 ADC1 1x 01 1000 N/A 01 1001 01 1010 01 1011 01 1100 01 1101 01 1110 1.1V (VBAND GAP) 01 1111 0V (GND) 10 0000 ADC8 10 0001 ADC9 10 0010 ADC10 10 0011 ADC11 10 0100 ADC12 10 0101 ADC13 10 0110 N/A ADC1 ADC0 40x 10 0111 Temperature Sensor 10 1000 N/A ADC0 ADC0 10x 10 1001 ADC5 ADC0 10x 10 1010 ADC6 ADC0 10x 10 1011 ADC7 ADC0 10x 10 1100 ADC4 ADC1 10x 10 1101 ADC5 ADC1 10x 10 1110 ADC6 ADC1 10x 10 1111 ADC7 ADC1 10x 11 0000 ADC4 ADC0 40x 11 0001 ADC5 ADC0 40x 11 0010 ADC6 ADC0 40x 11 0011 ADC7 ADC0 40x 11 0100 ADC4 ADC1 40x 11 0101 ADC5 ADC1 40x 11 0110 ADC6 ADC1 40x 11 0111 ADC7 ADC1 40x 11 1000 ADC4 ADC0 200x 11 1001 ADC5 ADC0 200x 11 1010 ADC6 ADC0 200x 11 1011 ADC7 ADC0 200x 11 1100 ADC4 ADC1 200x 11 1101 ADC5 ADC1 200x 11 1110 ADC6 ADC1 200x 11 1111 ADC7 ADC1 200x また、アナログ入力にはシングルエンド伝送と差動伝送がある。 シングルエンド伝送とは、1本の信号線でGNDとの電圧の差で信号を伝達する方法 差動伝送とは、2本の信号線を使って両方の信号線の電圧の差を使って信号を伝達する方法 いずれの方法も一長一短があるが、より高速に長距離の信号伝送を行いたい場合はノイズに強い差動伝送が使われる。 AD変換スタート(ADCSRA:ADSTビット(第6ビット)) ADSTビットを1にするとAD変換をスタートする。連続変換中にAD変換を停止させたい場合は、0にする。 各レジスタのビットの配置は、以下の通り。 ADCSRAレジスタのビット配置 bitの位置 (ビットの名前) 7 (ADEN) 6 (ADSC) 5 (ADATE) 4 (ADIF) 3 (ADIE) 2 (ADPS2) 1 (ADPS1) 0 (ADPS0) 機能 ADEN=1 ADCを起動 ADEN=0 ADCを停止 ADSC=1 AD変換スタート ADSC=0 AD変換停止 「2.AD変換の 起動設定」を参照 AD変換終了 割り込みフラグ (「3.割り込み設定」を参照) ADIE=1 AD変換終了割り 込みを有効 ADIE=0 AD変換終了割り 込みを無効 (「3.割り込み設定」を参照) システムクロック の分周比 000 = 1/2 001 = 1/2 010 = 1/4 011 = 1/8 100 = 1/16 101 = 1/32 110 = 1/64 111 = 1/128 初期値 0 0 0 0 0 0 0 0 ADCSRBレジスタのビット配置 bitの位置 (ビットの名称) 7 (ADHSM) 6 (ACME) 5 (MUX5) 4 - 3 (ADTS3) 2 (ADTS2) 1 (ADTS1) 0 (ADTS0S0) 機能 高速変換モード 「表:アナログ入力チャンネルの選択」を参照 - 「表:トリガモード一覧」を参照 初期値 0 0 0 0 0 0 0 0 ADMUXレジスタのビット配置 bitの位置 (ビットの名前) 7 (REFS1) 6 (REFS0) 5 (ADLAR) 4 (MUX4) 3 (MUX3) 2 (MUX2) 1 (MUX1) 0 (MUX0) 機能 「表:基準電圧減の選択」参照 「表:AD変換結果のレイアウト」参照 「表:アナログ入力チャンネルの選択」参照 初期値 0 0 0 0 0 0 0 0 DIDR1レジスタのビット配置 bitの位置 (ビットの名称) 7 (ADC7D) 6 (ADC6D) 5 (ADC5D) 4 (ADC4D) 3 - 2 - 1 (ADC1D) 0 (ADC0D) 機能 MUX5~0で選択したピンについて、当該ビットを1にセットすると、デジタル入力機能がOFFとなり、 消費電力を削減できる。 初期値 0 0 0 0 0 0 0 0 DIDR0レジスタのビット配置 bitの位置 (ビットの名称) 7 - 6 - 5 (ADC13D) 4 (ADC12D) 3 (ADC11D) 2 (ADC10D) 1 (ADC9D) 0 (ADC8D) 機能 MUX5~0で選択したピンについて、当該ビットを1にセットすると、デジタル入力機能がOFFとなり、 消費電力を削減できる。 初期値 0 0 0 0 0 0 0 0 AD変換の入力ピン配置 前述の通り、ATMega32U4マイコンには12本のアナログ入力がある。それぞれの入力と、基板上のピンの対応は、以下の通り。 サンプルプログラム 以下の様に、スライドボリュームをADC0に接続し、ボリュームのつまみの位置によってLED(PC7)が点滅するプログラム例を、以下に示す。 スライドボリュームの出力は、0~5Vの間で変化するためADC0の入力電圧も、同様に変化する。この時のAD変換後の数値は、0~1023となる。 ○単発変換によるサンプル /* * ADの単発変換のサンプルプログラム */ #define F_CPU 16000000UL // 16MHz動作 _delay_ms()などに関係 #include avr/io.h #include util/delay.h #include avr/interrupt.h int main() { unsigned int t; CLKPR = 0x80; CLKPR = 0; // 16MHz動作のための設定 DDRC = 0b10000000; // デバッグ用のLED(PC7)の設定 // ADCの初期化 ADMUX |= _BV(REFS0); // 電源5Vを使用、ADC0を使用, データ右詰め ADCSRA |= _BV(ADEN) | _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0); // ADEN, ADSC, CK/128 ADCSRA |= _BV(ADSC); // ADをスタート while(1) { if (ADCSRA _BV(ADIF)) { // AD変換の終了を確認 ADCSRA |= _BV(ADIF); t = ADC; // ADCは16bit幅で、8bitずつ2回に分けてアクセスされるので、 // 変数アクセス中に割り込みが発生しないように注意すること if (t 512) { PORTC = 0b10000000; } else { PORTC = 0b00000000; } ADCSRA |= _BV(ADSC); // ADを再スタート } } } ○連続変換によるサンプル /* * ADの連続変換のサンプルプログラム * #define F_CPU 16000000UL // 16MHz動作 _delay_ms()などに関係 #include avr/io.h #include util/delay.h #include avr/interrupt.h int main() { unsigned int t; CLKPR = 0x80; CLKPR = 0; // 16MHz動作のための設定 DDRC = 0b10000000; // デバッグ用のLED(PC7)の設定 // ADCの初期化 ADMUX |= _BV(REFS0); // 電源5Vを使用、ADC0を使用, データ右詰め ADCSRA |= _BV(ADEN) | _BV(ADPS2) | _BV(ADATE)| _BV(ADPS1) | _BV(ADPS0); // ADEN, ADSC, CK/128 ADCSRB = 0b11110000; // ADTS3~0を0で連続変換 ADCSRA |= _BV(ADSC); // ADをスタート while(1) { if (ADCSRA _BV(ADIF)) { // AD変換の終了を確認 t = ADC; // ADCは16bit幅で、8bitずつ2回に分けてアクセスされるので、 // 変数アクセス中に割り込みが発生しないように注意すること if (t 512) { PORTC = 0b10000000; } else { PORTC = 0b00000000; } } } } AD変換と割り込み /* * AD割り込みのサンプルプログラム */ #define F_CPU 16000000UL // 16MHz動作 _delay_ms()などに関係 #include avr/io.h #include util/delay.h #include avr/interrupt.h // 割り込みハンドラISR(ADC_vect) { unsigned int t; t = ADC; // ADCは16bit幅で、8bitずつ2回に分けてアクセスされるので、 // 変数アクセス中に割り込みが発生しないように注意すること if (t 512) { PORTC = 0b10000000; } else { PORTC = 0b00000000; } } int main() { CLKPR = 0x80; CLKPR = 0; // 16MHz動作のための設定 DDRC = 0b10000000; // デバッグ用のLED(PC7)の設定 // ADCの初期化 ADMUX |= _BV(REFS0); // Vcc(5V)を基準、ADC0を使用, データ右詰め ADCSRA |= _BV(ADEN) |_BV(ADIE)| _BV(ADATE) | _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0); // ADEN, ADIE, ADATE, CK/128 ADCSRB = 0b11110000; // 連続変換 ADCSRA |= _BV(ADSC); // ADをスタート sei(); // 全ての割り込みを許可 while(1) { } }
https://w.atwiki.jp/fysl/pages/257.html
アットウィキの使い方 よくある質問/利用に関して - アットウィキ(@WIKI)ご利用ガイド - atwiki(アットウィキ) https //w.atwiki.jp/guide/pages/30.html アットウィキの基本操作/その他/ページの編集権限または閲覧権限を変更する - アットウィキ(@WIKI)ご利用ガイド - atwiki(アットウィキ) https //w.atwiki.jp/guide/pages/1186.html
https://w.atwiki.jp/studiozodiac/pages/542.html
Day by day/2007年09月13日/絵描きチャットルーム利用に際して Day by day/2007年09月13日/絵描きチャット会 #blognavi
https://w.atwiki.jp/dayz777/
コールオブデューティー ブラックオプスディクラシファイド(通称 COD BOD) ○クランメンバー○ §クランリーダー§ ○viset777(SRしかできないw ちょいちょいキル稼いでいくStyle) ∇クランメンバー∇ ○kurafutopop (SR AT専門) ○yukito2391 (SR アシスト専門) ○SHANA-TUNA-3150(特にポジション決まってない新入クラメン)
https://w.atwiki.jp/dayz777/pages/3.html
更新履歴 取得中です。 ここを編集
https://w.atwiki.jp/affiliking3/pages/21.html
■オートレジスターの使い方 アフィリキングの機能「オートレジスター」の使い方について解説します。 オートレジスターは、はてなブックマーク、YahooブックマークFC2、livedoorなどのアカウントを 自動で取得する機能です。 自動でYahooメールのアカウントを取得し、yahooメールアドレスを基に上記のアカウントを 順次取得してきます。 使い方は以下のとおりです。 まず、アカウント取得に関する設定を行います。 「設定」をクリックします 設定サブウィンドウで、ID桁数とパスワードを指定し、アカウントを取得したいサイトを選択します。 出力先フォルダーは取得アカウントをまとめたCSVファイルの保存先です。 設定サブウィンドウを×ボタンで閉じると、設定完了となります。 「開始」をクリックし、自動取得を開始します。 yahooの画像認証が表示されるので、入力し、OKをクリックしていきます。 画像認証があるサイトに関しては、オートレジスターで画像認証を行う 必要があるので、逐一入力して認証します。 取得結果はログで随時確認できます。 取得が終わると、設定サブウィンドウで設定した出力先にCSVファイルとして 保存されます。
https://w.atwiki.jp/studiozodiac/pages/608.html
Day by day/2007年11月30日/辛さの基準が分からない Day by day/2007年11月30日/どこぞのコミュニティ #blognavi